import com.easyscript.analysis.DepthFirstAdapter;
import com.easyscript.node.AAscendentePTipoOrden;
import com.easyscript.node.ABoolPTipo;
import com.easyscript.node.ACharaPTipo;
import com.easyscript.node.ACondi1PCondicion;
import com.easyscript.node.ACondi2PCondicion;
import com.easyscript.node.ACondi3PCondicion;
import com.easyscript.node.ACondi4PCondicion;
import com.easyscript.node.ACondi5PCondicion;
import com.easyscript.node.ACuentaPOperador;
import com.easyscript.node.ADecimPTipo;
import com.easyscript.node.ADescendentePTipoOrden;
import com.easyscript.node.ADroPInicial;
import com.easyscript.node.AEliminaPDrop;
import com.easyscript.node.AEntPTipo;
import com.easyscript.node.AFechPTipo;
import com.easyscript.node.AMaximoPOperador;
import com.easyscript.node.AMinimoPOperador;
import com.easyscript.node.AMultiPCondiciones;
import com.easyscript.node.AMultiPIdentifier;
import com.easyscript.node.AMultiPVariables;
import com.easyscript.node.ANumeri1PTipo;
import com.easyscript.node.ANumeriPTipo;
import com.easyscript.node.AOper1POperaciones;
import com.easyscript.node.AOperPOperaciones;
import com.easyscript.node.APActualiza;
import com.easyscript.node.APConWhere;
import com.easyscript.node.APCreateTabla;
import com.easyscript.node.APInserta;
import com.easyscript.node.APOrdena;
import com.easyscript.node.APSeleccion;
import com.easyscript.node.APTop;
import com.easyscript.node.APUpdate;
import com.easyscript.node.APromedioPOperador;
import com.easyscript.node.ASelecPInicial;
import com.easyscript.node.ASinglePCondiciones;
import com.easyscript.node.ASinglePIdentifier;
import com.easyscript.node.ASinglePVariables;
import com.easyscript.node.ASumaPOperador;
import com.easyscript.node.ATablaPDesdeTabla;
import com.easyscript.node.ATextPTipo;
import com.easyscript.node.ATodoPIdentifier;
import com.easyscript.node.AUpdaPInicial;
import com.easyscript.node.AVariable1PTiposVariables;
import com.easyscript.node.AVariable2PTiposVariables;
import com.easyscript.node.AYPUniones;
import com.easyscript.node.PPOperaciones;
import com.easyscript.node.PPUniones;
import com.easyscript.node.TColumna;
import com.easyscript.node.TTabla;


public class Translation extends DepthFirstAdapter{
	String consulta="";
	String[] columnas;

	public Translation(String consulta)
	{
		Compiler com = new Compiler(this, consulta);
	}
	 public void caseAPSeleccion(APSeleccion node)
	    {
	        inAPSeleccion(node);
	        if(node.getSelecciona() != null)
	        {
	            consulta+="SELECT ";
	        }
	        if(node.getPTop() != null)
	        {
//	            node.getPTop().apply(this);
	            APTop top = (APTop) node.getPTop();
	            consulta+="TOP "+(Integer.parseInt(top.getInteger().getText().trim()))+" ";
	        }
	        if(node.getPOperaciones() != null)
	        {
	        	if(node.getPOperaciones() instanceof AOperPOperaciones)
	        	{
	        		AOperPOperaciones opera = (AOperPOperaciones)node.getPOperaciones();
	        		Object operador = opera.getPIdentifier();
	        		if(operador instanceof ATodoPIdentifier)
	        		{
	        			consulta+="* ";
	        		}
	        		else if(operador instanceof AMultiPIdentifier)
	        		{
	        			consulta+=opera.getPIdentifier();
	        			columnas = opera.getPIdentifier().toString().replace(" ", "").split(",");
	        		}
	        		else if(operador instanceof ASinglePIdentifier)
	        		{
	        			consulta+=opera.getPIdentifier();
	        			columnas = new String[1];
	        			columnas[0]=opera.getPIdentifier().toString().trim();
	        		}
	        	}
	        	else 
	        	{
	        		AOper1POperaciones opera = (AOper1POperaciones)node.getPOperaciones();
	        		Object operador = opera.getPOperador();
	        		if(operador instanceof ASumaPOperador)
	        		{
	        			consulta+="SUM ("+opera.getIdentifier()+") ";
	        		}
	        		else if(operador instanceof APromedioPOperador)
	        		{
	        			consulta+="AVG ("+opera.getIdentifier()+") ";
	        		}
	        		else if(operador instanceof ACuentaPOperador)
	        		{
	        			consulta+="COUNT("+opera.getIdentifier()+") ";
	        		}
	        		else if(operador instanceof AMaximoPOperador)
	        		{
	        			consulta+="MAX ("+opera.getIdentifier()+") ";
	        		}
	        		else if(operador instanceof AMinimoPOperador)
	        		{
	        			consulta+="MIN ("+opera.getIdentifier()+") ";
	        		}
	        	}
	            
	        }
	        if(node.getPUnion() != null)
	        {
	            node.getPUnion().apply(this);
	        }
	        if(node.getDesde() != null)
	        {
	            node.getDesde().apply(this);
	            consulta+="FROM ";
	        }
	        if(node.getPTablas() != null)
	        {
	            node.getPTablas().apply(this);
	            consulta+=(node.getPTablas().toString())+" ";
	        }
	        if(node.getPConWhere() != null)
	        {
//	            node.getPConWhere().apply(this);
	        	APConWhere opera = (APConWhere)node.getPConWhere();
	        	Object operacion = opera.getPCondiciones();
	        	consulta+="WHERE ";
	        	condicionWhere(operacion);
	        }
	        if(node.getPOrdena() != null)
	        {
	            Object objeto = ((APOrdena)node.getPOrdena()).getPTipoOrden();
	            consulta+="ORDER BY ";
	            consulta+=((APOrdena)node.getPOrdena()).getIdentifier();
	            if(objeto instanceof AAscendentePTipoOrden)
	            {
	            	consulta+="ASC ";
	            }
	            else if(objeto instanceof ADescendentePTipoOrden)
	            {
	            	consulta+="DESC ";
	            }
	        }
	        outAPSeleccion(node);
	    }
    public void condicionWhere(Object operacion)
    {
    	if(operacion instanceof ASinglePCondiciones)
    	{
    		Object compara = ((ASinglePCondiciones)operacion).getPCondicion();
    		realizarComparacion(compara);
    	}
    	else if(operacion instanceof AMultiPCondiciones)
    	{
    		Object compara = ((AMultiPCondiciones)operacion).getPCondicion();
    		realizarComparacion(compara);
    		consulta+=definirOperacion(((AMultiPCondiciones)operacion).getPUniones());
    		condicionWhere(((AMultiPCondiciones) operacion).getPCondiciones());
    	}
    }
    public String definirOperacion(PPUniones uniones)
    {
    	if(uniones instanceof AYPUniones)
    		return "AND ";
    	else
    		return "OR ";
    }
    public void realizarComparacion(Object node)
    {
    	
    	if(node instanceof ACondi1PCondicion)
		{
			consulta+=((ACondi1PCondicion) node).getLeft()+"="+((ACondi1PCondicion) node).getRight();
		}
    	else if(node instanceof ACondi2PCondicion)
    	{
    		consulta+=((ACondi2PCondicion) node).getLeft()+">"+((ACondi2PCondicion) node).getRight();
    	}
    	else if(node instanceof ACondi3PCondicion)
    	{
    		consulta+=((ACondi3PCondicion) node).getLeft()+"<"+((ACondi3PCondicion) node).getRight();
    	}
    	else if(node instanceof ACondi4PCondicion)
    	{
    		consulta+=((ACondi4PCondicion) node).getLeft()+"like "+((ACondi4PCondicion) node).getPIdenComo();
    		System.out.println();
    	}
    	else if(node instanceof ACondi5PCondicion)
    	{
//    		consulta+=((ACondi5PCondicion) node).getLeft()+"like"+((ACondi5PCondicion) node).getRight();
    	}
    }
    public void caseAPCreateTabla(APCreateTabla node)
    {
        inAPCreateTabla(node);
        if(node.getCrearTabla() != null)
        {
            consulta+="Create Table ";
        }
        if(node.getIdentifier() != null)
        {
//            node.getIdentifier().apply(this);
        	consulta+=node.getIdentifier().getText();
        }
        if(node.getLPar() != null)
        {
            consulta+="( ";
        }
        if(node.getPVariables() != null)
        {
        	crearTabla(node.getPVariables());
            System.out.println();
        }
        if(node.getRPar() != null)
        {
        	consulta+=") ";
        }
        outAPCreateTabla(node);
    }
    public void crearTabla(Object node)
    {
    	if(node instanceof ASinglePVariables)
    	{
    		System.out.println();
    		tiposVariables(((ASinglePVariables)node).getPTipo());
    	}
    	else if(node instanceof AMultiPVariables)
    	{
    		tiposVariables(((AMultiPVariables)node).getPTipo());
    		consulta+=", ";
    		crearTabla(((AMultiPVariables)node).getPVariables());
    		
    	}
    }
    public void tiposVariables(Object nodo)
    {
    	if(nodo instanceof AEntPTipo)
		{
    		consulta+=((AEntPTipo)nodo).getEntero();
			consulta+=" int ";
		}
		else if(nodo instanceof ABoolPTipo)
		{
			consulta+=((ABoolPTipo)nodo).getBuleano();
			consulta+=" bit ";
		}
		else if(nodo instanceof ACharaPTipo)
		{
			consulta+=""+((ACharaPTipo)nodo).getCaracteres();
			consulta+=" char( "+((ACharaPTipo)nodo).getInteger()+") ";
		}
		else if(nodo instanceof ANumeriPTipo)
		{
			ANumeriPTipo ho = ((ANumeriPTipo)nodo);
			consulta+=""+ho.getNumerico();
			consulta+=" numeric ("+ho.getLeft()+","+ho.getRigth()+") ";
		}
		else if(nodo instanceof ANumeri1PTipo)
		{
			ANumeri1PTipo ho = ((ANumeri1PTipo)nodo);
			consulta+=""+ho.getNumerico();
			consulta+=" numeric ("+ho.getInteger()+") ";
		}
		else if(nodo instanceof AFechPTipo)
		{
			AFechPTipo fe = ((AFechPTipo)nodo);
			consulta+=fe.getFecha();
			consulta+=" date";
		}
		else if(nodo instanceof ATextPTipo)
		{
			ATextPTipo te = ((ATextPTipo)nodo);
			consulta+=te.getTexto();
			consulta+=" text";
		}
		else if(nodo instanceof ADecimPTipo)
		{
			ADecimPTipo dec = ((ADecimPTipo)nodo);
			consulta+=dec.getDecimal();
			consulta+=" decimal ("+dec.getLeft()+","+dec.getRigth()+")";
		}
//		{numeri}numerico l_par [left]:integer comma [rigth]:integer r_par|
//		{numeri1}numerico l_par integer r_par |
//		{fech}fecha |
//		{text}texto |
//		{decim}decimal l_par [left]:integer comma [rigth]:integer r_par;

    }
    public void caseAPUpdate(APUpdate node)
    {
        inAPUpdate(node);
//        update Producto set Nombre = 'Cheesse Cake' where ID_Producto=122
        if(node.getActualiza() != null)
        {
//            node.getActualiza().apply(this);
            consulta+="Update ";
        }
        if(node.getIdentifier() != null)
        {
            consulta+=node.getIdentifier().getText()+" ";
        }
        if(node.getCon() != null)
        {
            consulta+="set ";
        }
        if(node.getPActualiza() != null)
        {
//            node.getPActualiza().apply(this);
        	APActualiza nodo = (APActualiza)node.getPActualiza();
        	consulta+=nodo.getIdentifier()+"=";
        	AVariable1PTiposVariables var = (AVariable1PTiposVariables)nodo.getPTiposVariables();
        	consulta+="'"+var.getPTiposVariablesValores()+"' ";
        }
        if(node.getPConWhere() != null)
        {
        	APConWhere opera = (APConWhere)node.getPConWhere();
        	Object operacion = opera.getPCondiciones();
        	consulta+="WHERE ";
        	condicionWhere(operacion);
        }
        outAPUpdate(node);
    }
    public void caseAEliminaPDrop(AEliminaPDrop node)
    {
        inAEliminaPDrop(node);
        if(node.getBorrarTabla() != null)
        {
            consulta+="Drop ";
        }
        if(node.getPDesdeTabla() != null)
        {
        	Object nodo = ((ATablaPDesdeTabla)node.getPDesdeTabla()).getTabla();
        	if(nodo instanceof TTabla)
        	{
        		consulta+="table ";
        	}
        	else if(nodo instanceof TColumna)
        	{
        		consulta+="column ";
        	}
        }
        if(node.getIdentifier() != null)
        {
        	consulta+= node.getIdentifier().getText();
        }
        outAEliminaPDrop(node);
    }
    public String getConsulta()
    {
    	return consulta;
    }
	public String[] getColumnas() {
		return columnas;
	}
	public void caseAPInserta(APInserta node)
    {
        inAPInserta(node);
        
        if(node.getInserta() != null)
        {
            consulta+="Insert into ";
        }
        if(node.getIdentifier() != null)
        {
            consulta+=node.getIdentifier().getText();
        }
        if(node.getPColumnas() != null)
        {
            consulta+=node.getPColumnas().toString();
        }
        if(node.getValores() != null)
        {
//            node.getValores().apply(this);
        	consulta+="Values ";
        }
        if(node.getLPar() != null)
        {
            consulta+="(";
        }
        if(node.getPTiposVariables() != null)
        {
        	valores(node.getPTiposVariables());
        }
        if(node.getRPar() != null)
        {
//            node.getRPar().apply(this);
        	consulta+=") ";
        }
        outAPInserta(node);
    }
	public void valores(Object objeto)
	{
		if(objeto instanceof AVariable1PTiposVariables)
		{
			AVariable1PTiposVariables opera = ((AVariable1PTiposVariables)objeto);
			consulta+=opera.getPTiposVariablesValores();
		}
		else if(objeto instanceof AVariable2PTiposVariables)
		{
			AVariable2PTiposVariables opera = ((AVariable2PTiposVariables)objeto);
			consulta+=opera.getPTiposVariablesValores()+",";
			valores(opera.getPTiposVariables());
		}
	}
}
